package com.ruoyi.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.*;
import java.util.Base64;

@Slf4j
public class SM4Utils {

    private static final String ALGORITHM_NAME = "SM4";
    private static final String ALGORITHM_NAME_CBC = "SM4/CBC/PKCS5Padding";

    private static final byte[] KEY = "FNGdDkZBvRcBeZZYrHW3Pw==".getBytes(); // 也必须是16字节长
    private static final byte[] IV = "v3mfZaWsIRRloQ==".getBytes(); // 也必须是16字节长

    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    // 生成密钥
    public static byte[] genKey() throws Exception {
        // 初始化密钥生成器
        KeyGenerator keyGenerator = KeyGenerator.getInstance("SM4");
        keyGenerator.init(new SecureRandom());

        // 生成密钥
        SecretKey secretKey = keyGenerator.generateKey();
        byte[] keyBytes = secretKey.getEncoded();

        // 转换为Base64编码以便打印和传输
        String base64Key = Base64.getEncoder().encodeToString(keyBytes);

        // 打印密钥
        System.out.println("SM4 Key: " + base64Key);
        return keyBytes;
    }


    // 加密
    public static String encrypt(String data) {
        try {
            Cipher cipher = Cipher.getInstance(ALGORITHM_NAME_CBC, "BC");

            byte[] decodekEY = Base64.getDecoder().decode(KEY);
            SecretKeySpec keySpec = new SecretKeySpec(decodekEY, ALGORITHM_NAME);
            IvParameterSpec ivSpec = new IvParameterSpec(IV);
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);

            byte[] encryptedBytes = cipher.doFinal(data.getBytes("UTF-8"));
            return Base64.getEncoder().encodeToString(encryptedBytes);
        } catch (Exception e) {
            log.error("加密失败,{}",e.getMessage());
            return data;
        }
    }

    // 解密
    public static String decrypt(String encryptedData){
        try {
            Cipher cipher = Cipher.getInstance(ALGORITHM_NAME_CBC, "BC");
            byte[] decodekEY = Base64.getDecoder().decode(KEY);
            SecretKeySpec keySpec = new SecretKeySpec(decodekEY, ALGORITHM_NAME);
            IvParameterSpec ivSpec = new IvParameterSpec(IV);
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);

            byte[] decodedBytes = Base64.getDecoder().decode(encryptedData);
            byte[] decryptedBytes = cipher.doFinal(decodedBytes);
            return new String(decryptedBytes,"UTF-8");
        } catch (Exception e) {
            log.error("解密失败,{}",e.getMessage());
            return encryptedData;
        }
    }



    // 字节数组转16进制字符串
    public static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }

    // 16进制字符串转字节数组
    public static byte[] hexToBytes(String hex) {
        byte[] bytes = new byte[hex.length() / 2];
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16);
        }
        return bytes;
    }
}
